package bma.common.langutil.xdom;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import bma.common.langutil.core.ClassUtil;
import bma.common.langutil.xdom.core.XdomBoolean;
import bma.common.langutil.xdom.core.XdomNULL;
import bma.common.langutil.xdom.core.XdomNumber;
import bma.common.langutil.xdom.core.XdomString;

public class XdomUtil {

	public static Xdom value(Object obj) {
		if (obj == null) {
			return XdomNULL.NULL;
		}
		if (obj instanceof String) {
			return new XdomString((String) obj);
		}
		if (obj instanceof Number) {
			return new XdomNumber((Number) obj);
		}
		if (obj instanceof Boolean) {
			return new XdomBoolean((Boolean) obj);
		}
		return null;
	}
	
	public static String toString(Xdom o) {
		StringBuilder sb = new StringBuilder();
		toString(o, sb);
		return sb.toString();
	}

	public static void toString(Xdom o, StringBuilder sb) {
		XdomType t = o == null ? XdomType.NULL : o.type();
		switch (t) {
		case ARRAY: {
			Iterator<Xdom> it = o.arrayIterator();
			sb.append('[');
			while (it.hasNext()) {
				Xdom v = it.next();
				toString(v, sb);
				if (it.hasNext()) {
					sb.append(", ");
				}
			}
			sb.append(']');
			break;
		}
		case BOOLEAN:
			sb.append(o.getBooleanValue());
			break;
		case MAP: {
			Iterator<String> it = o.mapNames();
			sb.append('{');
			while (it.hasNext()) {
				String n = it.next();
				Xdom v = o.get(n);
				sb.append(n).append('=');
				toString(v, sb);
				if (it.hasNext()) {
					sb.append(", ");
				}
			}
			sb.append('}');
			break;
		}
		case NULL:
			sb.append("NULL");
			break;
		case NUMBER:
			sb.append(o.getNumberValue());
			break;
		case STRING:
			sb.append('"').append(o.getStringValue()).append('"');
			break;
		}
	}

	public static Object createObject(Xdom dom, Class expectClass) throws Exception {
		if(dom==null)return null;
		switch (dom.type()) {
		case ARRAY: {
			List r = null;
			if (expectClass != null && !expectClass.isInterface()) {
				r = (List) expectClass.newInstance();
			} else {
				r = new ArrayList();
			}
			return r;
		}
		case BOOLEAN:
			return dom.getBooleanValue();
		case MAP: {
			Object r = null;
			String type = dom.xtype();
			if (type != null) {
				expectClass = ClassUtil.forName(type);
			}
			if (expectClass != null && !expectClass.isInterface()) {
				r = expectClass.newInstance();
			} else {
				r = new HashMap();
			}
			return r;
		}
		case NULL:
			return null;
		case NUMBER:
			return dom.getNumberValue();
		case STRING:
			return dom.getStringValue();
		}
		return null;
	}
}
